package com.example.fms.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.fms.constant.ChineseConstant;
import com.example.fms.constant.NumberConstant;
import com.example.fms.dto.req.AddMinOrderRuleReqDto;
import com.example.fms.dto.req.AddStandardFreightReqDto;
import com.example.fms.dto.req.StandardFreightReqDto;
import com.example.fms.dto.resp.StandardFreightRespDto;
import com.example.fms.entity.MinOrderRule;
import com.example.fms.entity.StandardFreightRule;
import com.example.fms.enums.CalculationRulesEnum;
import com.example.fms.enums.DeliveryTypeEnum;
import com.example.fms.enums.ExtentEnum;
import com.example.fms.exception.BusinessException;
import com.example.fms.exception.ExceptionEnum;
import com.example.fms.mapper.StandardFreightRuleMapper;
import com.example.fms.service.StandardFreightRuleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class StandardFreightRuleServiceImpl extends ServiceImpl<StandardFreightRuleMapper, StandardFreightRule> implements StandardFreightRuleService {

    @Resource
    StandardFreightRuleMapper standardFreightRuleMapper;
    @Override
    public Page<StandardFreightRespDto> getStandardFreightList(StandardFreightReqDto req) {
        Page<StandardFreightRespDto> page = new Page<>(req.getPageNum(), req.getPageSize());
        List<StandardFreightRespDto> standardFreightList = standardFreightRuleMapper.getStandardFreightList(page, req);
        if (CollectionUtil.isNotEmpty(standardFreightList)) {
            standardFreightList.forEach(s->{
                s.setType(DeliveryTypeEnum.getNameByCode(s.getType()));
                s.setExtent(ExtentEnum.getNameByCode(s.getExtent()));
                s.setCalculationRules(CalculationRulesEnum.getNameByCode(s.getCalculationRules()));
            });
        }
        page.setRecords(standardFreightList);
        return page;
    }

    @Override
    @Transactional
    public Boolean addStandardFreightRule(AddStandardFreightReqDto req) {
        //创建qw
        LambdaQueryWrapper<StandardFreightRule> qw = Wrappers.lambdaQuery();
        List<StandardFreightRule> standardFreightRulesList = null;

        //如果市和区为空的时候
        if (StrUtil.isBlank(req.getCity()) && StrUtil.isBlank(req.getArea())) {
            qw.eq(StandardFreightRule::getWarehouse, req.getWarehouse())
                    .eq(StandardFreightRule::getProvince, req.getProvince())
                    .eq(StandardFreightRule::getType, req.getType());
        } else if (!StrUtil.isBlank(req.getCity()) && StrUtil.isBlank(req.getArea())) {
            //如果市不为空，区为空
            qw.eq(StandardFreightRule::getWarehouse, req.getWarehouse())
                    .eq(StandardFreightRule::getProvince, req.getProvince())
                    .eq(StandardFreightRule::getType, req.getType())
                    .in(StandardFreightRule::getCity, req.getCity(),ChineseConstant.NULL);
        } else if (!StrUtil.isBlank(req.getCity()) && !StrUtil.isBlank(req.getArea())) {
            //如果市不为空，区不为空
            qw.eq(StandardFreightRule::getWarehouse, req.getWarehouse())
                    .eq(StandardFreightRule::getProvince, req.getProvince())
                    .eq(StandardFreightRule::getType, req.getType())
                    .in(StandardFreightRule::getCity, req.getCity(),ChineseConstant.NULL)
                    .in(StandardFreightRule::getArea, req.getArea(),ChineseConstant.NULL);
        } else if (StrUtil.isBlank(req.getCity()) && !StrUtil.isBlank(req.getArea())) {
            throw new BusinessException(ExceptionEnum.THE_CITY_IS_EMPTY);
        }

        standardFreightRulesList = standardFreightRuleMapper.selectList(qw);

        List<Boolean> addBooleanList = add(standardFreightRulesList, req);
        //如果add中没有false
        if (!addBooleanList.contains(false)) {
            save(req);
        } else {
            throw new BusinessException(ExceptionEnum.STANDARD_CONFLICT_RULE);
        }
        return true;
    }

    private  List<Boolean> add(List<StandardFreightRule> standardFreightRulesList, AddStandardFreightReqDto req) {

        List<Boolean> booleanList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(standardFreightRulesList)) {
            standardFreightRulesList.forEach( s -> {
                if ((req.getExtent().equals(NumberConstant.ZERO) || req.getExtent().equals(NumberConstant.ONE))
                        && (s.getExtent().equals(NumberConstant.ZERO) || s.getExtent().equals(NumberConstant.ONE))) {
                    booleanList.add(false);
                }
                if ((req.getExtent().equals(NumberConstant.THREE) || req.getExtent().equals(NumberConstant.TWO))
                        && (s.getExtent().equals(NumberConstant.TWO) || s.getExtent().equals(NumberConstant.THREE))) {
                    booleanList.add(false);
                }
                if ((Integer.parseInt(s.getNumber()) > Integer.parseInt(req.getNumber()))
                        && (s.getExtent().equals(NumberConstant.THREE) || s.getExtent().equals(NumberConstant.TWO))) {
                    booleanList.add(false);
                }
                if ((Integer.parseInt(s.getNumber()) < Integer.parseInt(req.getNumber()))
                        && (s.getExtent().equals(NumberConstant.ONE) || s.getExtent().equals(NumberConstant.ZERO))) {
                    booleanList.add(false);
                }
            });
        }
        return booleanList;
    }

    @Override
    public Boolean upDateStandardFreightRule(AddStandardFreightReqDto req) {
        if (req.getId() == null) {
            throw new BusinessException(ExceptionEnum.ID_ONT_NUll);
        }
        //创建qw
        LambdaQueryWrapper<StandardFreightRule> qw = Wrappers.lambdaQuery();
        List<StandardFreightRule> standardFreightRulesList = null;

        //如果市和区为空的时候
        if (StrUtil.isBlank(req.getCity()) && StrUtil.isBlank(req.getArea())) {
            qw.ne(StandardFreightRule::getId, req.getId())
                    .eq(StandardFreightRule::getWarehouse, req.getWarehouse())
                    .eq(StandardFreightRule::getProvince, req.getProvince())
                    .eq(StandardFreightRule::getType, req.getType());

        } else if (!StrUtil.isBlank(req.getCity()) && StrUtil.isBlank(req.getArea())) {
            //如果市不为空，区为空
            qw.ne(StandardFreightRule::getId, req.getId())
                    .eq(StandardFreightRule::getWarehouse, req.getWarehouse())
                    .eq(StandardFreightRule::getProvince, req.getProvince())
                    .eq(StandardFreightRule::getType, req.getType())
                    .in(StandardFreightRule::getCity, req.getCity(),ChineseConstant.NULL);
        } else if (!StrUtil.isBlank(req.getCity()) && !StrUtil.isBlank(req.getArea())) {
            //如果市不为空，区不为空
            qw.ne(StandardFreightRule::getId, req.getId())
                    .eq(StandardFreightRule::getWarehouse, req.getWarehouse())
                    .eq(StandardFreightRule::getProvince, req.getProvince())
                    .eq(StandardFreightRule::getType, req.getType())
                    .in(StandardFreightRule::getCity, req.getCity(),ChineseConstant.NULL)
                    .in(StandardFreightRule::getArea, req.getArea(),ChineseConstant.NULL);
        } else if (StrUtil.isBlank(req.getCity()) && !StrUtil.isBlank(req.getArea())) {
            throw new BusinessException(ExceptionEnum.THE_CITY_IS_EMPTY);
        }

        standardFreightRulesList = standardFreightRuleMapper.selectList(qw);

        List<Boolean> addBooleanList = add(standardFreightRulesList, req);
        //如果add中没有false
        if (!addBooleanList.contains(false)) {
            save(req);
        } else {
            throw new BusinessException(ExceptionEnum.STANDARD_CONFLICT_RULE);
        }

        return true;
    }

    @Override
    public Boolean deleteStandardFreightRule(Long id) {
        int i = standardFreightRuleMapper.deleteById(id);
        if (i == Integer.parseInt(NumberConstant.ZERO)) {
            throw new BusinessException(ExceptionEnum.DELETE_NUll);
        }
        return true;
    }


    private void save(AddStandardFreightReqDto req) {
        if(StrUtil.isEmpty(req.getArea())) {
            req.setArea(ChineseConstant.NULL);
        }
        if(StrUtil.isEmpty(req.getCity())) {
            req.setCity(ChineseConstant.NULL);
        }
        LambdaQueryWrapper<StandardFreightRule> dw = Wrappers.lambdaQuery();
        dw.eq(StandardFreightRule::getRuleName, req.getRuleName())
                .ne(req.getId() != null,StandardFreightRule::getId, req.getId());
        //规则名称校验
        List<StandardFreightRule> standardFreightRuleList = standardFreightRuleMapper.selectList(dw);
        if (CollectionUtil.isNotEmpty(standardFreightRuleList)) {
            throw new BusinessException(ExceptionEnum.MIN_CONFLICT_RULE_NAME);
        } else {
            StandardFreightRule standardFreightRule = new StandardFreightRule();
            //将req复制到minOrderRule
            BeanUtils.copyProperties(req, standardFreightRule);
            //插入
            if (req.getId() != null){
                log.info("修改规则:{}", standardFreightRule);
                standardFreightRuleMapper.updateById(standardFreightRule);
            } else {
                log.info("插入规则:{}", standardFreightRule);
                standardFreightRuleMapper.insert(standardFreightRule);
            }
        }
    }
}
